/**
 * @author Utilisateur
 */

var Game = Class.extend({
	init: function(parent){
		this.parent = parent;
		this.nbRound = 1; //Round number
		this.playerList = []; //List of all the players
		this.isStarted = true; //Has the game started ?
		this.draggable = false;
		this.cardDragged;
		this.mouseX;
		this.mouseY;
		
		//CONSTANTS
		this.cardWidth = 71;
		this.cardHeight = 96;
		this.cardLeftPadding = 15;
		this.cardPosY = 10;
		this.width = 1280;
		this.height = 720;
		
		this.canvas = document.getElementById("airedejeu");
		this.rankListNames = ["President","Vice-President","Secretary","Janitor"];
		this.lastHand = [];
		this.hands = [];
		
		this.turnIndex = 0;
		this.turnCounter = 0;
		this.roundWinner = 0;
		
		this.passBox = new ReadyBox(this,50,575,"Pass");
		this.readyBox = new ReadyBox(this,50,650,"Ready");
		
		this.rankList = [];
		this.tempRankList = []
		this.deck = new Deck(); //All cards possible
		this.roundWinnder = [];
		
		this.playerList.push(new Human(this,0,"Moi",50,600,1));
		this.playerList.push(new Computer(this,1,"Jack",50,650,1));
		this.playerList.push(new Computer(this,2,"Joe",50,650,1));
		this.playerList.push(new Computer(this,3,"John",50,650,1));
	
		//FUNCTION CALLS
		
		this.draft();
		this.start();
	},
	draft: function(){
	
		console.log("Initial draft");
		var temp = [];
	
		//Pick cards and put them in temp hashmap
		for (var i=0; i<this.playerList.length; i++) {
			 
			c = this.deck.randomCard();
			temp.push({
				index: i,
				number: c.number,
				suit: c.suit
	        });
		}	
		
		temp = this.sortCards(temp,"");

		for (var i=0; i<temp.length; i++) {		 
			this.playerList[temp[i].index].position = i;
		}
	},
	
	start: function(){
		this.rankList = this.returnRanks();
		this.deck = new Deck();
		this.distributeCards();
		this.sortPlayerHand();
		this.setCardCoords();
		this.turn();
	},
	

	
	setCardCoords: function(){
		this.cardWidth = 71;
		this.cardHeight = 96;
		this.cardLeftPadding = 15;
		this.cardposY= 10;
	
		var posX = 15;
		var posY = 10;
	
		var size = Object.size(this.playerList[0].hand);
		for (var i=0; i < size;i++) {
			this.playerList[0].hand[i].x = this.cardLeftPadding+(i*this.cardWidth);
			this.playerList[0].hand[i].y = this.cardposY;
		}
	},
	
	distributeCards: function(){
		console.log("Distributing cards");
		// Give 2 cards first to the first 2 ranks
		
		for (var i=0;i<2;i++) {
			c = this.deck.randomCard();
			this.playerList[0].addCard(c);
		}
		
		for (var i=0;i<2;i++) {
			c = this.deck.randomCard();
			this.playerList[1].addCard(c);
		}
		
		c = this.deck.randomCard();
		this.playerList[2].addCard(c);
		
		c = this.deck.randomCard();
		this.playerList[3].addCard(c);	
		
		// Give the remaining cards.
		var counter = 47;
		do {
			for (var j=0;j<this.playerList.length;j++) {
				var c = this.deck.randomCard();
				this.playerList[j].addCard(c);
				counter-=1;
			}
		} while (counter>0);
		
	},
		
	turn: function(){
		if (!this.rankList[this.turnIndex].noCardsLeft) {
			this.rankList[this.turnIndex].turn = true;
			if (!this.rankList[this.turnIndex].isHuman) {
				this.rankList[this.turnIndex].play();
			}
		}
	},

	nextTurn: function(){
		this.rankList[this.turnIndex].turn = false;
		this.rankList[this.turnIndex].ready = false;

		if (!this.rankList[this.turnIndex].pass && !this.rankList[this.turnIndex].done) {
			this.lastHand = this.rankList[this.turnIndex].tempHand.slice(0);
			this.hands.push(this.lastHand);
			this.roundWinner = this.turnIndex;
			this.rankList[this.turnIndex].tempHand = [];
			if (this.rankList[this.turnIndex].hand.length == 0) {
				this.rankList[this.turnIndex].noCardsLeft = true;
			}
		}
		this.rankList[this.turnIndex].pass = false;
		
		//Check if last player has no cards left then give him a rank for next round
		if (this.rankList[this.turnIndex].noCardsLeft) {
			console.log(this.rankList[this.turnIndex].name + " is out of cards!");
			var size = Object.size(this.tempRankList);
			this.tempRankList.push({
				index: this.rankList[this.turnIndex].index,
				position: size,
	        });
			size++;
			this.rankList[this.turnIndex].noCardsLeft = false;
			this.rankList[this.turnIndex].done = true;
			if (size == this.rankList.length) {
				this.roundOver = true;	
			}
		}
			
		this.turnCounter++;
		this.turnIndex++;

		if (this.roundOver) {
			this.roundOver = false;
			for (var i=0;i<this.tempRankList.length;i++) {
				this.playerList[this.tempRankList[i].index].position = this.tempRankList[i].position;
			}
			this.tempRankList = [];
			this.turnCounter = 0;
			this.turnIndex = 0;
			this.roundWinnder = null;
			this.start();	
		}
		else {
			if(this.turnCounter == this.rankList.length) {
					this.turnIndex = this.roundWinner;
					this.lastHand=[];
					this.hands = [];
					this.turnCounter = 0;
					console.log("****************** NEW TURN *****************");
				}
			else {
				if (this.turnIndex == this.rankList.length)
				this.turnIndex = 0;
			}

			this.turn();
		}
	},

	roundover: function() {
		var size = Object.size(this.playerList);
		var counter = 0;
		for (var i=0; i < size;i++) {
			if (playerList[i].hand == []) {
				counter++;
			}
		}
		if (counter == this.playerList.length-1) {
			return true;
		}
		else return false;
	},
	

	verifClickedCard: function(index){
					
		if (this.playerList[0].turn) {
			
			if (this.lastHand.length != 0) {
				if (this.highestCard(this.playerList[0].hand[index],this.lastHand[0]) && this.playerList[0].tempHand.length < this.lastHand.length) {
					return true;
				}
				else
					return false;
			}
			else if (this.playerList[0].tempHand.length != 0) {
				if (this.playerList[0].hand[index].number == this.playerList[0].tempHand[0].number && this.playerList[0].hand[index].name != this.playerList[0].tempHand[0].name) {
					return true;
				}
				else
					return false;

				return true;
			}
			else
				return true;
		}
		return false;
	
	},
	
	highlightPlayableCards: function(index){
		//Change clicked card highlight to CLicked or unclicked
		var highlight = false;
		if (this.playerList[0].hand[index].highlightClicked == true) {
			highlight = false;
			this.removeFromTempHand(index);
		}
		else {
			highlight = true;
			this.addToTempHand(index);
		}
		
		this.playerList[0].hand[index].highlightClicked = highlight;
		
		var size = Object.size(this.playerList[0].hand);
		for (var i=0; i < size;i++) {
			if (this.playerList[0].hand[i].number == this.playerList[0].hand[index].number) {
				
				if (this.playerList[0].hand[i].highlightClicked == false) {
					if (this.playerList[0].tempHand.length == 0) 
						this.playerList[0].hand[i].highlightSameValue = false;
					else
						this.playerList[0].hand[i].highlightSameValue = true;
				}
			}
		}
	},
	
	addToTempHand: function(index){
		this.playerList[0].tempHand.push(this.playerList[0].hand[index]);
	},
	
	removeFromTempHand: function(index){
		var size = Object.size(this.playerList[0].tempHand);
		for (var i=0; i < size;i++) {
			if (this.playerList[0].hand[index].name == this.playerList[0].tempHand[i].name) {
				this.playerList[0].tempHand.splice(i,1);
			}
		}
	},

	//*****************************SORTS
	
	sortPlayerHand: function(){
		for (var i=0;i<this.playerList.length; i++) {
			this.playerList[i].hand = this.sortCards(this.playerList[i].hand,"asc");
		}
	},
	
	sortCards: function(list,order) {
		if (order == "asc") {
			list.sort(function (a,b) {
			if (a.number == 99) {
				if (b.number == 99) {
					if (a.suit < b.suit) {
						return false;
					}
				}
				return true;
			}
			if (b.number == 99) {
				return false;
			}
			else if (a.number < 3) {
				if (b.number < 3) {
					return (a.number > b.number);
				}
					return true;
			}
			else if (b.number <3) {
				return false;
			}
			else {
				return a.number > b.number ;
			}
			if (a.suit > b.suit) return -1;
			if (a.suit <b.suit) return 1;				
			});
			
		}
		else {
			list.sort(function(a, b) {
				if (a.number != b.number) {
					return a.number < b.number;
				}
				else if (a.number == 99) {
					if (b.number == 99) {
						if (a.suit > b.suit) {
							return false;
						}
					}
					return true;
				}
				else if (a.number < 3) {
					if (b.number < 3) {
						return (a.number < b.number);
					}
					else {
						return false;
					}
				}
				else if (b.number <3) {
					return true;
				}
				else {
					return a.number < b.number ;
				}
				if (a.suit < b.suit) return -1;
				if (a.suit >b.suit) return 1;				
			});			
		}
		return list;
	},
	
	highestCard: function(c1,c2,checkSuit) {

		if (c1.number == 99) {
			if (c1.suit < c2.suit) {
				return false;
			}
			return true;
		}
		if (c2.number == 99)
			return false;
		else if (c1.number < 3) {
			if (c2.number < 3) {
				return (c1.number > c2.number);
			}
			else {
				return true;
			}
		}
		else if (c2.number <3) {
			return false;
		}
		else {
			return c1.number > c2.number ;
		}
	},
	
 	lowestCard: function(c1,c2) {
		if (c1.number == 99) {
			if (c1.suit > c2.suit) {
				return false;
			}
			return true;
		}
		else if (c1.number < 3) {
			if (c2.number < 3) {
				return (c1.number < c2.number);
			}
			else {
				return false;
			}
		}
		else if (c2.number <3) {
			return true;
		}
		else {
			return c1.number < c2.number ;
		}
	},	
	
	//EVENTS
	mouseMoved: function(x, y){
		this.mouseX = x;
		this.mouseY = y;
		if (this.draggable) {
			if (this.cardDragged.highlight == true) 
				this.cardDragged.highlight = false;
			this.cardDragged.x = x ;
			this.cardDragged.y = y ;
		}
	},
	
	clickEvent: function(x, y){
		
		// Check if clicked on start box
		if (this.playerList[0].tempHand.length != 0) {
			if (x >= this.readyBox.x && x <= this.readyBox.x+this.readyBox.width) {
				if (y >= this.readyBox.y && y <= this.readyBox.y+this.readyBox.height) {
					for (var i=0;i<this.playerList[0].hand.length;i++) {
						for (var j=0;j<this.playerList[0].tempHand.length;j++) {
							if (this.playerList[0].tempHand[j].name == this.playerList[0].hand[i].name) {
								this.playerList[0].hand.splice(i,1);
							}
						}
					}
					this.playerList[0].ready = true;				
				}
			}	
		}
		else {
			if (x >= this.passBox.x && x <= this.passBox.x+this.passBox.width) {
				if (y >= this.passBox.y && y <= this.passBox.y+this.passBox.height) {
					this.playerList[0].pass = true;				
				}
			}		
		}
	
		// Check if clicked on a card
		
		var size = Object.size(this.playerList[0].hand);
		for (var i=0; i < size;i++) {
			var temp = this.playerList[0].hand[i];
			if (x >= temp.x && x <= temp.x+this.cardWidth) {
				if (y >= temp.y && y <= temp.y+this.cardHeight) {
					console.log("Clicked on a card");
					if (this.verifClickedCard(i) == true) {
						this.highlightPlayableCards(i);
						this.cardDragged = this.playerList[0].hand[i];
					}
				}
			}
		}
	},
	

	
	unclickEvent: function(){
		this.draggable = false;
		this.cardDragged = null;
	},
	
	returnRanks: function(){
		var arr = this.playerList.slice(0);
	    arr.sort(function(a, b) {
			return a.position > b.position;
		});
		return arr;
	},
	
	showRanks: function() {
		var size = this.playerList.length;
		for (var i=0; i<size; i++) {		 
			console.log("Player # " + i + " Player rank  : " + this.playerList[i].position + " and name is : " + this.playerList[i].name);
		}
	}
});


Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

/***CLASSES***********/

function Point(x, y){
    this.x = x || 0;
    this.y = y || 0;
};
